#pragma once
#include "AutoPt.h"

enum thread_state_t {
	INIT,
	START,
	JOINED,
	STOP
};

class IRunnable :public CYKCounter{
public:
	virtual int32_t operator()(const bool* isstopped, void* param = NULL) = 0;
	virtual ~IRunnable() { }
};


typedef void*(*run_func_t)(const bool *, void *param);
typedef CYKAutoPoint<IRunnable> RunnableAutoPt;

class CYKThread:public CYKCounter{

public:
	CYKThread(const RunnableAutoPt &pt,bool detached=false);
	CYKThread(run_func_t func, void *arg = NULL, bool detached = false);
	~CYKThread();

public:
	bool start();
	bool join();
	bool stop();
#ifdef _WIN32
	DWORD get_thread_id() const;
	operator HANDLE();
#else
	pthread_t get_thread_id() const;
#endif


private:
	bool setDetached();
#ifdef _WIN32
	static DWORD __stdcall thread_start_func(LPVOID lpParam);
#else
	static void* thread_start_func(void* arg);
#endif

private:
	bool _use_functor;
	RunnableAutoPt _functor;
	run_func_t _func_ptr;
	void* _func_arg;
	CYKSemaphore _sema;
	volatile bool _detached;
	thread_state_t _state;
	bool _isstopped;
#ifdef _WIN32
	HANDLE _handle;
	DWORD _thread_id;
#else
	pthread_t _thread;
#endif
};

typedef CYKAutoPoint<CYKThread> CYKAutoThread;